<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="robots" content="noodp" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
        <title>使用docker安装mysql - 负责和大饼的博客</title><meta name="Description" content="想专注于学点手艺"><meta property="og:title" content="使用docker安装mysql" />
<meta property="og:description" content="使用docker安装MySQL 准备Dockerfile FROM debian:stretch-slim # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added RUN groupadd -r mysql &amp;&amp; useradd -r -g mysql mysql RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends gnupg dirmngr" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://amath0312.github.com/mysql_in_docker/" />
<meta property="article:published_time" content="2019-08-12T21:17:43+08:00" />
<meta property="article:modified_time" content="2019-08-12T21:17:43+08:00" />
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="使用docker安装mysql"/>
<meta name="twitter:description" content="使用docker安装MySQL 准备Dockerfile FROM debian:stretch-slim # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added RUN groupadd -r mysql &amp;&amp; useradd -r -g mysql mysql RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends gnupg dirmngr"/>
<meta name="application-name" content="负责和大饼的博客">
<meta name="apple-mobile-web-app-title" content="负责和大饼的博客"><link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><link rel="canonical" href="https://amath0312.github.com/mysql_in_docker/" /><link rel="prev" href="https://amath0312.github.com/zentao_in_docker/" /><link rel="next" href="https://amath0312.github.com/jenkins_in_docker/" /><link rel="stylesheet" href="/lib/normalize/normalize.min.css"><link rel="stylesheet" href="/css/style.min.css"><link rel="stylesheet" href="/lib/fontawesome-free/all.min.css"><link rel="stylesheet" href="/lib/animate/animate.min.css"><script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "使用docker安装mysql",
        "inLanguage": "zh-CN",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https:\/\/amath0312.github.com\/mysql_in_docker\/"
        },"genre": "posts","keywords": "docker","wordcount":  1444 ,
        "url": "https:\/\/amath0312.github.com\/mysql_in_docker\/","datePublished": "2019-08-12T21:17:43+08:00","dateModified": "2019-08-12T21:17:43+08:00","publisher": {
            "@type": "Organization",
            "name": "Author"},"author": {
                "@type": "Person",
                "name": "Author"
            },"description": ""
    }
    </script></head>
    <body header-desktop="" header-mobile=""><script type="text/javascript">(window.localStorage && localStorage.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : '' === 'dark')) && document.body.setAttribute('theme', 'dark');</script>

        <div id="mask"></div><div class="wrapper"><header class="desktop" id="header-desktop">
    <div class="header-wrapper">
        <div class="header-title">
            <a href="/" title="负责和大饼的博客">负责和大饼的博客</a>
        </div>
        <div class="menu">
            <div class="menu-inner"><a class="menu-item" href="/posts/"> Blog </a><a class="menu-item" href="/categories/"> Categories </a><a class="menu-item" href="/tags/"> Tags </a><a class="menu-item" href="/about/"> About </a><span class="menu-item delimiter"></span><span class="menu-item search" id="search-desktop">
                        <input type="text" placeholder="Search titles or contents..." id="search-input-desktop">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-desktop" title="Search">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-desktop" title="Clear">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-desktop">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </span><a href="javascript:void(0);" class="menu-item theme-switch" title="Switch Theme">
                    <i class="fas fa-adjust fa-fw"></i>
                </a>
            </div>
        </div>
    </div>
</header><header class="mobile" id="header-mobile">
    <div class="header-container">
        <div class="header-wrapper">
            <div class="header-title">
                <a href="/" title="负责和大饼的博客">负责和大饼的博客</a>
            </div>
            <div class="menu-toggle" id="menu-toggle-mobile">
                <span></span><span></span><span></span>
            </div>
        </div>
        <div class="menu" id="menu-mobile"><div class="search-wrapper">
                    <div class="search mobile" id="search-mobile">
                        <input type="text" placeholder="Search titles or contents..." id="search-input-mobile">
                        <a href="javascript:void(0);" class="search-button search-toggle" id="search-toggle-mobile" title="Search">
                            <i class="fas fa-search fa-fw"></i>
                        </a>
                        <a href="javascript:void(0);" class="search-button search-clear" id="search-clear-mobile" title="Clear">
                            <i class="fas fa-times-circle fa-fw"></i>
                        </a>
                        <span class="search-button search-loading" id="search-loading-mobile">
                            <i class="fas fa-spinner fa-fw fa-spin"></i>
                        </span>
                    </div>
                    <a href="javascript:void(0);" class="search-cancel" id="search-cancel-mobile">
                        Cancel
                    </a>
                </div><a class="menu-item" href="/posts/" title="">Blog</a><a class="menu-item" href="/categories/" title="">Categories</a><a class="menu-item" href="/tags/" title="">Tags</a><a class="menu-item" href="/about/" title="">About</a><a href="javascript:void(0);" class="menu-item theme-switch" title="Switch Theme">
                <i class="fas fa-adjust fa-fw"></i>
            </a></div>
    </div>
</header>
<div class="search-dropdown desktop">
    <div id="search-dropdown-desktop"></div>
</div>
<div class="search-dropdown mobile">
    <div id="search-dropdown-mobile"></div>
</div>
<main class="main">
                <div class="container"><div class="toc" id="toc-auto">
            <h2 class="toc-title">Contents</h2>
            <div class="toc-content" id="toc-content-auto"></div>
        </div><article class="page single"><h1 class="single-title animated flipInX">使用docker安装mysql</h1><div class="post-meta">
            <div class="post-meta-line"><span class="post-author"><a href="/" title="Author" rel=" author" class="author"><i class="fas fa-user-circle fa-fw"></i>Author</a></span>&nbsp;<span class="post-category">included in <a href="/categories/docker/"><i class="far fa-folder fa-fw"></i>docker</a></span></div>
            <div class="post-meta-line"><i class="far fa-calendar-alt fa-fw"></i>&nbsp;<time datetime="2019-08-08">2019-08-08</time>&nbsp;<i class="fas fa-pencil-alt fa-fw"></i>&nbsp;1444 words&nbsp;
                <i class="far fa-clock fa-fw"></i>&nbsp;3 minutes&nbsp;</div>
        </div><div class="details toc" id="toc-static"  kept="">
                <div class="details-summary toc-title">
                    <span>Contents</span>
                    <span><i class="details-icon fas fa-angle-right"></i></span>
                </div>
                <div class="details-content toc-content" id="toc-content-static"><nav id="TableOfContents">
  <ul>
    <li><a href="#准备dockerfile">准备<code>Dockerfile</code></a></li>
    <li><a href="#准备docker-entrypointsh">准备<code>docker-entrypoint.sh</code></a></li>
    <li><a href="#构建镜像">构建镜像</a></li>
    <li><a href="#启动容器">启动容器</a></li>
  </ul>
</nav></div>
            </div><div class="content" id="content"><h1 id="使用docker安装mysql">使用docker安装MySQL</h1>
<h2 id="准备dockerfile">准备<code>Dockerfile</code></h2>
<div class="highlight"><pre class="chroma"><code class="language-shell" data-lang="shell">FROM debian:stretch-slim

<span class="c1"># add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added</span>
RUN groupadd -r mysql <span class="o">&amp;&amp;</span> useradd -r -g mysql mysql

RUN apt-get update <span class="o">&amp;&amp;</span> apt-get install -y --no-install-recommends gnupg dirmngr <span class="o">&amp;&amp;</span> rm -rf /var/lib/apt/lists/*

<span class="c1"># add gosu for easy step-down from root</span>
ENV GOSU_VERSION 1.7
RUN <span class="nb">set</span> -x <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> apt-get update <span class="o">&amp;&amp;</span> apt-get install -y --no-install-recommends ca-certificates wget <span class="o">&amp;&amp;</span> rm -rf /var/lib/apt/lists/* <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> wget -O /usr/local/bin/gosu <span class="s2">&#34;https://github.com/tianon/gosu/releases/download/</span><span class="nv">$GOSU_VERSION</span><span class="s2">/gosu-</span><span class="k">$(</span>dpkg --print-architecture<span class="k">)</span><span class="s2">&#34;</span> <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> wget -O /usr/local/bin/gosu.asc <span class="s2">&#34;https://github.com/tianon/gosu/releases/download/</span><span class="nv">$GOSU_VERSION</span><span class="s2">/gosu-</span><span class="k">$(</span>dpkg --print-architecture<span class="k">)</span><span class="s2">.asc&#34;</span> <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> <span class="nb">export</span> <span class="nv">GNUPGHOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>mktemp -d<span class="k">)</span><span class="s2">&#34;</span> <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> gpgconf --kill all <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> rm -rf <span class="s2">&#34;</span><span class="nv">$GNUPGHOME</span><span class="s2">&#34;</span> /usr/local/bin/gosu.asc <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> chmod +x /usr/local/bin/gosu <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> gosu nobody <span class="nb">true</span> <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> apt-get purge -y --auto-remove ca-certificates wget

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-get update <span class="o">&amp;&amp;</span> apt-get install -y --no-install-recommends <span class="se">\
</span><span class="se"></span><span class="c1"># for MYSQL_RANDOM_ROOT_PASSWORD</span>
		pwgen <span class="se">\
</span><span class="se"></span><span class="c1"># FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:</span>
<span class="c1"># File::Basename</span>
<span class="c1"># File::Copy</span>
<span class="c1"># Sys::Hostname</span>
<span class="c1"># Data::Dumper</span>
		perl <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> rm -rf /var/lib/apt/lists/*

RUN <span class="nb">set</span> -ex<span class="p">;</span> <span class="se">\
</span><span class="se"></span><span class="c1"># gpg: key 5072E1F5: public key &#34;MySQL Release Engineering &lt;mysql-build@oss.oracle.com&gt;&#34; imported</span>
	<span class="nv">key</span><span class="o">=</span><span class="s1">&#39;A4A9406876FCBD3C456770C88C718D3B5072E1F5&#39;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>	<span class="nb">export</span> <span class="nv">GNUPGHOME</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>mktemp -d<span class="k">)</span><span class="s2">&#34;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>	gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys <span class="s2">&#34;</span><span class="nv">$key</span><span class="s2">&#34;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>	gpg --batch --export <span class="s2">&#34;</span><span class="nv">$key</span><span class="s2">&#34;</span> &gt; /etc/apt/trusted.gpg.d/mysql.gpg<span class="p">;</span> <span class="se">\
</span><span class="se"></span>	gpgconf --kill all<span class="p">;</span> <span class="se">\
</span><span class="se"></span>	rm -rf <span class="s2">&#34;</span><span class="nv">$GNUPGHOME</span><span class="s2">&#34;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>	apt-key list &gt; /dev/null

ENV MYSQL_MAJOR 5.6
ENV MYSQL_VERSION 5.6.45-1debian9

RUN <span class="nb">echo</span> <span class="s2">&#34;deb http://repo.mysql.com/apt/debian/ stretch mysql-</span><span class="si">${</span><span class="nv">MYSQL_MAJOR</span><span class="si">}</span><span class="s2">&#34;</span> &gt; /etc/apt/sources.list.d/mysql.list

<span class="c1"># the &#34;/var/lib/mysql&#34; stuff here is because the mysql-server postinst doesn&#39;t have an explicit way to disable the mysql_install_db codepath besides having a database already &#34;configured&#34; (ie, stuff in /var/lib/mysql/mysql)</span>
<span class="c1"># also, we set debconf keys to make APT a little quieter</span>
RUN <span class="o">{</span> <span class="se">\
</span><span class="se"></span>		<span class="nb">echo</span> mysql-community-server mysql-community-server/data-dir <span class="k">select</span> <span class="s1">&#39;&#39;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>		<span class="nb">echo</span> mysql-community-server mysql-community-server/root-pass password <span class="s1">&#39;&#39;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>		<span class="nb">echo</span> mysql-community-server mysql-community-server/re-root-pass password <span class="s1">&#39;&#39;</span><span class="p">;</span> <span class="se">\
</span><span class="se"></span>		<span class="nb">echo</span> mysql-community-server mysql-community-server/remove-test-db <span class="k">select</span> false<span class="p">;</span> <span class="se">\
</span><span class="se"></span>	<span class="o">}</span> <span class="p">|</span> debconf-set-selections <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> apt-get update <span class="o">&amp;&amp;</span> apt-get install -y mysql-server<span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">MYSQL_VERSION</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">&amp;&amp;</span> rm -rf /var/lib/apt/lists/* <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> rm -rf /var/lib/mysql <span class="o">&amp;&amp;</span> mkdir -p /var/lib/mysql /var/run/mysqld <span class="se">\
</span><span class="se"></span>	<span class="o">&amp;&amp;</span> chown -R mysql:mysql /var/lib/mysql /var/run/mysqld <span class="se">\
</span><span class="se"></span><span class="c1"># ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime</span>
	<span class="o">&amp;&amp;</span> chmod <span class="m">777</span> /var/run/mysqld <span class="se">\
</span><span class="se"></span><span class="c1"># comment out a few problematic configuration values</span>
	<span class="o">&amp;&amp;</span> find /etc/mysql/ -name <span class="s1">&#39;*.cnf&#39;</span> -print0 <span class="se">\
</span><span class="se"></span>		<span class="p">|</span> xargs -0 grep -lZE <span class="s1">&#39;^(bind-address|log)&#39;</span> <span class="se">\
</span><span class="se"></span>		<span class="p">|</span> xargs -rt -0 sed -Ei <span class="s1">&#39;s/^(bind-address|log)/#&amp;/&#39;</span> <span class="se">\
</span><span class="se"></span><span class="c1"># don&#39;t reverse lookup hostnames, they are usually another container</span>
	<span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s1">&#39;[mysqld]\nskip-host-cache\nskip-name-resolve&#39;</span> &gt; /etc/mysql/conf.d/docker.cnf

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh <span class="c1"># backwards compat</span>
ENTRYPOINT <span class="o">[</span><span class="s2">&#34;docker-entrypoint.sh&#34;</span><span class="o">]</span>

EXPOSE <span class="m">3306</span>
CMD <span class="o">[</span><span class="s2">&#34;mysqld&#34;</span><span class="o">]</span>
</code></pre></div><h2 id="准备docker-entrypointsh">准备<code>docker-entrypoint.sh</code></h2>
<div class="highlight"><pre class="chroma"><code class="language-shell" data-lang="shell"><span class="cp">#!/bin/bash
</span><span class="cp"></span><span class="nb">set</span> -eo pipefail
<span class="nb">shopt</span> -s nullglob

<span class="c1"># if command starts with an option, prepend mysqld</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">1</span><span class="p">:</span><span class="nv">0</span><span class="p">:</span><span class="nv">1</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s1">&#39;-&#39;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
	<span class="nb">set</span> -- mysqld <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span>
<span class="k">fi</span>

<span class="c1"># skip setup if they want an option that stops mysqld</span>
<span class="nv">wantHelp</span><span class="o">=</span>
<span class="k">for</span> arg<span class="p">;</span> <span class="k">do</span>
	<span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$arg</span><span class="s2">&#34;</span> in
		-<span class="s1">&#39;?&#39;</span><span class="p">|</span>--help<span class="p">|</span>--print-defaults<span class="p">|</span>-V<span class="p">|</span>--version<span class="o">)</span>
			<span class="nv">wantHelp</span><span class="o">=</span><span class="m">1</span>
			<span class="nb">break</span>
			<span class="p">;;</span>
	<span class="k">esac</span>
<span class="k">done</span>

<span class="c1"># usage: file_env VAR [DEFAULT]</span>
<span class="c1">#    ie: file_env &#39;XYZ_DB_PASSWORD&#39; &#39;example&#39;</span>
<span class="c1"># (will allow for &#34;$XYZ_DB_PASSWORD_FILE&#34; to fill in the value of</span>
<span class="c1">#  &#34;$XYZ_DB_PASSWORD&#34; from a file, especially for Docker&#39;s secrets feature)</span>
file_env<span class="o">()</span> <span class="o">{</span>
	<span class="nb">local</span> <span class="nv">var</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span>
	<span class="nb">local</span> <span class="nv">fileVar</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">var</span><span class="si">}</span><span class="s2">_FILE&#34;</span>
	<span class="nb">local</span> <span class="nv">def</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">2</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span>
	<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="p">!var</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="p">!fileVar</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
		<span class="nb">echo</span> &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s2">&#34;error: both </span><span class="nv">$var</span><span class="s2"> and </span><span class="nv">$fileVar</span><span class="s2"> are set (but are exclusive)&#34;</span>
		<span class="nb">exit</span> <span class="m">1</span>
	<span class="k">fi</span>
	<span class="nb">local</span> <span class="nv">val</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$def</span><span class="s2">&#34;</span>
	<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="p">!var</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
		<span class="nv">val</span><span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="p">!var</span><span class="si">}</span><span class="s2">&#34;</span>
	<span class="k">elif</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="p">!fileVar</span><span class="k">:-</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
		<span class="nv">val</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>&lt; <span class="s2">&#34;</span><span class="si">${</span><span class="p">!fileVar</span><span class="si">}</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span>
	<span class="k">fi</span>
	<span class="nb">export</span> <span class="s2">&#34;</span><span class="nv">$var</span><span class="s2">&#34;</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$val</span><span class="s2">&#34;</span>
	<span class="nb">unset</span> <span class="s2">&#34;</span><span class="nv">$fileVar</span><span class="s2">&#34;</span>
<span class="o">}</span>

<span class="c1"># usage: process_init_file FILENAME MYSQLCOMMAND...</span>
<span class="c1">#    ie: process_init_file foo.sh mysql -uroot</span>
<span class="c1"># (process a single initializer file, based on its extension. we define this</span>
<span class="c1"># function here, so that initializer scripts (*.sh) can use the same logic,</span>
<span class="c1"># potentially recursively, or override the logic used in subsequent calls)</span>
process_init_file<span class="o">()</span> <span class="o">{</span>
	<span class="nb">local</span> <span class="nv">f</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span><span class="p">;</span> <span class="nb">shift</span>
	<span class="nb">local</span> <span class="nv">mysql</span><span class="o">=(</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> <span class="o">)</span>

	<span class="k">case</span> <span class="s2">&#34;</span><span class="nv">$f</span><span class="s2">&#34;</span> in
		*.sh<span class="o">)</span>     <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">: running </span><span class="nv">$f</span><span class="s2">&#34;</span><span class="p">;</span> . <span class="s2">&#34;</span><span class="nv">$f</span><span class="s2">&#34;</span> <span class="p">;;</span>
		*.sql<span class="o">)</span>    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">: running </span><span class="nv">$f</span><span class="s2">&#34;</span><span class="p">;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> &lt; <span class="s2">&#34;</span><span class="nv">$f</span><span class="s2">&#34;</span><span class="p">;</span> <span class="nb">echo</span> <span class="p">;;</span>
		*.sql.gz<span class="o">)</span> <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">: running </span><span class="nv">$f</span><span class="s2">&#34;</span><span class="p">;</span> gunzip -c <span class="s2">&#34;</span><span class="nv">$f</span><span class="s2">&#34;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="nb">echo</span> <span class="p">;;</span>
		*<span class="o">)</span>        <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$0</span><span class="s2">: ignoring </span><span class="nv">$f</span><span class="s2">&#34;</span> <span class="p">;;</span>
	<span class="k">esac</span>
	<span class="nb">echo</span>
<span class="o">}</span>

_check_config<span class="o">()</span> <span class="o">{</span>
	<span class="nv">toRun</span><span class="o">=(</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> --verbose --help --log-bin-index<span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>mktemp -u<span class="k">)</span><span class="s2">&#34;</span> <span class="o">)</span>
	<span class="k">if</span> ! <span class="nv">errors</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">toRun</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> 2&gt;<span class="p">&amp;</span><span class="m">1</span> &gt;/dev/null<span class="k">)</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
		cat &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s">&lt;&lt;-EOM
</span><span class="s">
</span><span class="s">			ERROR: mysqld failed while attempting to check config
</span><span class="s">			command was: &#34;${toRun[*]}&#34;
</span><span class="s">
</span><span class="s">			$errors
</span><span class="s">		EOM</span>
		<span class="nb">exit</span> <span class="m">1</span>
	<span class="k">fi</span>
<span class="o">}</span>

<span class="c1"># Fetch value from server config</span>
<span class="c1"># We use mysqld --verbose --help instead of my_print_defaults because the</span>
<span class="c1"># latter only show values present in config files, and not server defaults</span>
_get_config<span class="o">()</span> <span class="o">{</span>
	<span class="nb">local</span> <span class="nv">conf</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span><span class="p">;</span> <span class="nb">shift</span>
	<span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> --verbose --help --log-bin-index<span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>mktemp -u<span class="k">)</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="p">|</span> awk <span class="s1">&#39;$1 == &#34;&#39;</span><span class="s2">&#34;</span><span class="nv">$conf</span><span class="s2">&#34;</span><span class="s1">&#39;&#34; { print $2; exit }&#39;</span>
<span class="o">}</span>

<span class="c1"># allow the container to be started with `--user`</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s1">&#39;mysqld&#39;</span> -a -z <span class="s2">&#34;</span><span class="nv">$wantHelp</span><span class="s2">&#34;</span> -a <span class="s2">&#34;</span><span class="k">$(</span>id -u<span class="k">)</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s1">&#39;0&#39;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
	_check_config <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span>
	<span class="nv">DATADIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>_get_config <span class="s1">&#39;datadir&#39;</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span>
	mkdir -p <span class="s2">&#34;</span><span class="nv">$DATADIR</span><span class="s2">&#34;</span>
	chown -R mysql:mysql <span class="s2">&#34;</span><span class="nv">$DATADIR</span><span class="s2">&#34;</span>
	<span class="nb">exec</span> gosu mysql <span class="s2">&#34;</span><span class="nv">$BASH_SOURCE</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span>
<span class="k">fi</span>

<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="s1">&#39;mysqld&#39;</span> -a -z <span class="s2">&#34;</span><span class="nv">$wantHelp</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
	<span class="c1"># still need to check config, container may have started with --user</span>
	_check_config <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span>
	<span class="c1"># Get config</span>
	<span class="nv">DATADIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>_get_config <span class="s1">&#39;datadir&#39;</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span>

	<span class="k">if</span> <span class="o">[</span> ! -d <span class="s2">&#34;</span><span class="nv">$DATADIR</span><span class="s2">/mysql&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
		file_env <span class="s1">&#39;MYSQL_ROOT_PASSWORD&#39;</span>
		<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&#34;</span><span class="nv">$MYSQL_ROOT_PASSWORD</span><span class="s2">&#34;</span> -a -z <span class="s2">&#34;</span><span class="nv">$MYSQL_ALLOW_EMPTY_PASSWORD</span><span class="s2">&#34;</span> -a -z <span class="s2">&#34;</span><span class="nv">$MYSQL_RANDOM_ROOT_PASSWORD</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">echo</span> &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s1">&#39;error: database is uninitialized and password option is not specified &#39;</span>
			<span class="nb">echo</span> &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s1">&#39;  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD&#39;</span>
			<span class="nb">exit</span> <span class="m">1</span>
		<span class="k">fi</span>

		mkdir -p <span class="s2">&#34;</span><span class="nv">$DATADIR</span><span class="s2">&#34;</span>

		<span class="nb">echo</span> <span class="s1">&#39;Initializing database&#39;</span>
		<span class="c1"># &#34;Other options are passed to mysqld.&#34; (so we pass all &#34;mysqld&#34; arguments directly here)</span>
		mysql_install_db --datadir<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$DATADIR</span><span class="s2">&#34;</span> --rpm --keep-my-cnf <span class="s2">&#34;</span><span class="si">${</span><span class="p">@:</span><span class="nv">2</span><span class="si">}</span><span class="s2">&#34;</span>
		<span class="nb">echo</span> <span class="s1">&#39;Database initialized&#39;</span>

		<span class="nv">SOCKET</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>_get_config <span class="s1">&#39;socket&#39;</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span><span class="k">)</span><span class="s2">&#34;</span>
		<span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> --skip-networking --socket<span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">SOCKET</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">&amp;</span>
		<span class="nv">pid</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$!</span><span class="s2">&#34;</span>

		<span class="nv">mysql</span><span class="o">=(</span> mysql --protocol<span class="o">=</span>socket -uroot -hlocalhost --socket<span class="o">=</span><span class="s2">&#34;</span><span class="si">${</span><span class="nv">SOCKET</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">)</span>

		<span class="k">for</span> i in <span class="o">{</span>30..0<span class="o">}</span><span class="p">;</span> <span class="k">do</span>
			<span class="k">if</span> <span class="nb">echo</span> <span class="s1">&#39;SELECT 1&#39;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="p">&amp;</span>&gt; /dev/null<span class="p">;</span> <span class="k">then</span>
				<span class="nb">break</span>
			<span class="k">fi</span>
			<span class="nb">echo</span> <span class="s1">&#39;MySQL init process in progress...&#39;</span>
			sleep <span class="m">1</span>
		<span class="k">done</span>
		<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$i</span><span class="s2">&#34;</span> <span class="o">=</span> <span class="m">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">echo</span> &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s1">&#39;MySQL init process failed.&#39;</span>
			<span class="nb">exit</span> <span class="m">1</span>
		<span class="k">fi</span>

		<span class="k">if</span> <span class="o">[</span> -z <span class="s2">&#34;</span><span class="nv">$MYSQL_INITDB_SKIP_TZINFO</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="c1"># sed is for https://bugs.mysql.com/bug.php?id=20545</span>
			mysql_tzinfo_to_sql /usr/share/zoneinfo <span class="p">|</span> sed <span class="s1">&#39;s/Local time zone must be set--see zic manual page/FCTY/&#39;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> mysql
		<span class="k">fi</span>

		<span class="k">if</span> <span class="o">[</span> ! -z <span class="s2">&#34;</span><span class="nv">$MYSQL_RANDOM_ROOT_PASSWORD</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">export</span> <span class="nv">MYSQL_ROOT_PASSWORD</span><span class="o">=</span><span class="s2">&#34;</span><span class="k">$(</span>pwgen -1 32<span class="k">)</span><span class="s2">&#34;</span>
			<span class="nb">echo</span> <span class="s2">&#34;GENERATED ROOT PASSWORD: </span><span class="nv">$MYSQL_ROOT_PASSWORD</span><span class="s2">&#34;</span>
		<span class="k">fi</span>

		<span class="nv">rootCreate</span><span class="o">=</span>
		<span class="c1"># default root to listen for connections from anywhere</span>
		file_env <span class="s1">&#39;MYSQL_ROOT_HOST&#39;</span> <span class="s1">&#39;%&#39;</span>
		<span class="k">if</span> <span class="o">[</span> ! -z <span class="s2">&#34;</span><span class="nv">$MYSQL_ROOT_HOST</span><span class="s2">&#34;</span> -a <span class="s2">&#34;</span><span class="nv">$MYSQL_ROOT_HOST</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s1">&#39;localhost&#39;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="c1"># no, we don&#39;t care if read finds a terminating character in this heredoc</span>
			<span class="c1"># https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151</span>
			<span class="nb">read</span> -r -d <span class="s1">&#39;&#39;</span> rootCreate <span class="s">&lt;&lt;-EOSQL || true
</span><span class="s">				CREATE USER &#39;root&#39;@&#39;${MYSQL_ROOT_HOST}&#39; IDENTIFIED BY &#39;${MYSQL_ROOT_PASSWORD}&#39; ;
</span><span class="s">				GRANT ALL ON *.* TO &#39;root&#39;@&#39;${MYSQL_ROOT_HOST}&#39; WITH GRANT OPTION ;
</span><span class="s">			EOSQL</span>
		<span class="k">fi</span>

		<span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s">&lt;&lt;-EOSQL
</span><span class="s">			-- What&#39;s done in this file shouldn&#39;t be replicated
</span><span class="s">			--  or products like mysql-fabric won&#39;t work
</span><span class="s">			SET @@SESSION.SQL_LOG_BIN=0;
</span><span class="s">
</span><span class="s">			DELETE FROM mysql.user WHERE user NOT IN (&#39;mysql.sys&#39;, &#39;mysqlxsys&#39;, &#39;root&#39;) OR host NOT IN (&#39;localhost&#39;) ;
</span><span class="s">			SET PASSWORD FOR &#39;root&#39;@&#39;localhost&#39;=PASSWORD(&#39;${MYSQL_ROOT_PASSWORD}&#39;) ;
</span><span class="s">			GRANT ALL ON *.* TO &#39;root&#39;@&#39;localhost&#39; WITH GRANT OPTION ;
</span><span class="s">			${rootCreate}
</span><span class="s">			DROP DATABASE IF EXISTS test ;
</span><span class="s">			FLUSH PRIVILEGES ;
</span><span class="s">		EOSQL</span>

		<span class="k">if</span> <span class="o">[</span> ! -z <span class="s2">&#34;</span><span class="nv">$MYSQL_ROOT_PASSWORD</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nv">mysql</span><span class="o">+=(</span> -p<span class="s2">&#34;</span><span class="si">${</span><span class="nv">MYSQL_ROOT_PASSWORD</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">)</span>
		<span class="k">fi</span>

		file_env <span class="s1">&#39;MYSQL_DATABASE&#39;</span>
		<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$MYSQL_DATABASE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">echo</span> <span class="s2">&#34;CREATE DATABASE IF NOT EXISTS \`</span><span class="nv">$MYSQL_DATABASE</span><span class="s2">\` ;&#34;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span>
			<span class="nv">mysql</span><span class="o">+=(</span> <span class="s2">&#34;</span><span class="nv">$MYSQL_DATABASE</span><span class="s2">&#34;</span> <span class="o">)</span>
		<span class="k">fi</span>

		file_env <span class="s1">&#39;MYSQL_USER&#39;</span>
		file_env <span class="s1">&#39;MYSQL_PASSWORD&#39;</span>
		<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$MYSQL_USER</span><span class="s2">&#34;</span> -a <span class="s2">&#34;</span><span class="nv">$MYSQL_PASSWORD</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">echo</span> <span class="s2">&#34;CREATE USER &#39;</span><span class="nv">$MYSQL_USER</span><span class="s2">&#39;@&#39;%&#39; IDENTIFIED BY &#39;</span><span class="nv">$MYSQL_PASSWORD</span><span class="s2">&#39; ;&#34;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span>

			<span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$MYSQL_DATABASE</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
				<span class="nb">echo</span> <span class="s2">&#34;GRANT ALL ON \`</span><span class="nv">$MYSQL_DATABASE</span><span class="s2">\`.* TO &#39;</span><span class="nv">$MYSQL_USER</span><span class="s2">&#39;@&#39;%&#39; ;&#34;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span>
			<span class="k">fi</span>

			<span class="nb">echo</span> <span class="s1">&#39;FLUSH PRIVILEGES ;&#39;</span> <span class="p">|</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span>
		<span class="k">fi</span>

		<span class="nb">echo</span>
		ls /docker-entrypoint-initdb.d/ &gt; /dev/null
		<span class="k">for</span> f in /docker-entrypoint-initdb.d/*<span class="p">;</span> <span class="k">do</span>
			process_init_file <span class="s2">&#34;</span><span class="nv">$f</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span>
		<span class="k">done</span>

		<span class="k">if</span> <span class="o">[</span> ! -z <span class="s2">&#34;</span><span class="nv">$MYSQL_ONETIME_PASSWORD</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
			<span class="s2">&#34;</span><span class="si">${</span><span class="nv">mysql</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s">&lt;&lt;-EOSQL
</span><span class="s">				ALTER USER &#39;root&#39;@&#39;%&#39; PASSWORD EXPIRE;
</span><span class="s">			EOSQL</span>
		<span class="k">fi</span>
		<span class="k">if</span> ! <span class="nb">kill</span> -s TERM <span class="s2">&#34;</span><span class="nv">$pid</span><span class="s2">&#34;</span> <span class="o">||</span> ! <span class="nb">wait</span> <span class="s2">&#34;</span><span class="nv">$pid</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">then</span>
			<span class="nb">echo</span> &gt;<span class="p">&amp;</span><span class="m">2</span> <span class="s1">&#39;MySQL init process failed.&#39;</span>
			<span class="nb">exit</span> <span class="m">1</span>
		<span class="k">fi</span>

		<span class="nb">echo</span>
		<span class="nb">echo</span> <span class="s1">&#39;MySQL init process done. Ready for start up.&#39;</span>
		<span class="nb">echo</span>
	<span class="k">fi</span>
<span class="k">fi</span>

<span class="nb">exec</span> <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span>

</code></pre></div><h2 id="构建镜像">构建镜像</h2>
<div class="highlight"><pre class="chroma"><code class="language-shell" data-lang="shell"><span class="c1"># 进入Dockerfile所在路径，执行以下命令</span>
docker build -t mysql:5.6 ./
</code></pre></div><h2 id="启动容器">启动容器</h2>
<div class="highlight"><pre class="chroma"><code class="language-shell" data-lang="shell"><span class="c1"># 表名、列名对大小写敏感</span>
docker run -p 13306:3306 -e <span class="nv">MYSQL_ROOT_PASSWORD</span><span class="o">=</span><span class="m">123456</span> -d --name mysql-server mysql:5.6

<span class="c1"># 忽略表名、列名大小写</span>
docker run -p 13306:3306 -e <span class="nv">MYSQL_ROOT_PASSWORD</span><span class="o">=</span><span class="m">123456</span> -d --name mysql-server mysql:5.6 --lower_case_table_names<span class="o">=</span><span class="m">1</span>
</code></pre></div><p>访问宿主机13306端口即可，用户名/密码：<code>root/123456</code></p>
</div><div class="post-footer" id="post-footer">
    <div class="post-info">
        <div class="post-info-line">
            <div class="post-info-mod">
                <span>Updated on 2019-08-08</span>
            </div>
            <div class="post-info-license"></div>
        </div>
        <div class="post-info-line">
            <div class="post-info-md"></div>
            <div class="post-info-share">
                <span></span>
            </div>
        </div>
    </div>

    <div class="post-info-more">
        <section class="post-tags"><i class="fas fa-tags fa-fw"></i>&nbsp;<a href="/tags/docker/">docker</a></section>
        <section>
            <span><a href="javascript:void(0);" onclick="window.history.back();">Back</a></span>&nbsp;|&nbsp;<span><a href="/">Home</a></span>
        </section>
    </div>

    <div class="post-nav"><a href="/zentao_in_docker/" class="prev" rel="prev" title="通过Docker安装禅道"><i class="fas fa-angle-left fa-fw"></i>通过Docker安装禅道</a>
            <a href="/jenkins_in_docker/" class="next" rel="next" title="使用docker安装jenkins">使用docker安装jenkins<i class="fas fa-angle-right fa-fw"></i></a></div>
</div>
</article></div>
            </main><footer class="footer">
        <div class="footer-container"><div class="footer-line">Powered by <a href="https://gohugo.io/" target="_blank" rel="noopener noreffer" title="Hugo 0.75.1">Hugo</a> | Theme - <a href="https://github.com/dillonzq/LoveIt" target="_blank" rel="noopener noreffer" title="LoveIt 0.2.10"><i class="far fa-kiss-wink-heart fa-fw"></i> LoveIt</a>
                </div><div class="footer-line"><i class="far fa-copyright fa-fw"></i><span itemprop="copyrightYear">2019 - 2020</span><span class="author" itemprop="copyrightHolder">&nbsp;<a href="/" target="_blank"></a></span>&nbsp;|&nbsp;<span class="license">本文采用<a rel="license" href="http://creativecommons.org/licenses/by-nc/4.0/" target="_blank">知识共享署名-非商业性使用 4.0 国际许可协议</a>进行许可</span></div>
        </div>
    </footer></div>

        <div id="fixed-buttons"><a href="#" id="back-to-top" class="fixed-button" title="Back to Top">
                <i class="fas fa-arrow-up fa-fw"></i>
            </a><a href="#" id="view-comments" class="fixed-button" title="View Comments">
                <i class="fas fa-comment fa-fw"></i>
            </a>
        </div><script type="text/javascript" src="/lib/smooth-scroll/smooth-scroll.min.js"></script><script type="text/javascript" src="/lib/autocomplete/autocomplete.min.js"></script><script type="text/javascript" src="/lib/algoliasearch/algoliasearch-lite.umd.min.js"></script><script type="text/javascript" src="/lib/lazysizes/lazysizes.min.js"></script><script type="text/javascript" src="/lib/clipboard/clipboard.min.js"></script><script type="text/javascript">window.config={"code":{"copyTitle":"Copy to clipboard","maxShownLines":10},"comment":{},"search":{"algoliaAppID":"JJRDOPDPLW","algoliaIndex":"amath_blog","algoliaSearchKey":"e529bedc6a3af35b53e2597f1c7550c2","highlightTag":"em","maxResultLength":10,"noResultsFound":"No results found","snippetLength":50,"type":"algolia"}};</script><script type="text/javascript" src="/js/theme.min.js"></script></body>
</html>
